﻿// ============================================================================
//  _ __   ___  ___  ___ _ __ ___  _   _
// | '_ \ / _ \/ __|/ _ \ '_ ` _ \| | | |
// | | | |  __/\__ \  __/ | | | | | |_| |
// |_| |_|\___||___/\___|_| |_| |_|\__,_|
//
// NES Emulator by daxnet, 2024
// MIT License
// ============================================================================

using System;
using System.Linq;
using System.Windows.Forms;
using Krypton.Navigator;
using NesEmu.Core;
using NesEmu.Explorer.Properties;

namespace NesEmu.Explorer.Pages;

public partial class FilePropertyPage : UserControl
{
    #region Private Fields

    private readonly FrmMain? _parent;

    #endregion Private Fields

    #region Public Constructors

    public FilePropertyPage(FrmMain parent)
        : this()
    {
        _parent = parent;
        _parent.OnMessageBroadcasted += ParentOnOnMessageBroadcasted;
    }

    #endregion Public Constructors

    #region Private Constructors

    private FilePropertyPage()
    {
        InitializeComponent();
    }

    #endregion Private Constructors

    #region Public Classes

    public sealed class Page : KryptonPage
    {
        #region Public Fields

        public const string PageName = "9AFF7373-BDA4-45A9-B04E-CF69B8585EF1";

        #endregion Public Fields

        #region Private Fields

        private readonly FilePropertyPage? _ctrl;

        #endregion Private Fields

        #region Public Constructors

        public Page(FrmMain parent, object? args = null)
            : base("NES Cartridge Property", Resources.ListProperty, PageName)
        {
            TextTitle = @"NES Cartridge Property";
            TextDescription = TextTitle;

            _ctrl = new FilePropertyPage(parent)
            {
                Dock = DockStyle.Fill
            };

            Controls.Add(_ctrl);
        }

        #endregion Public Constructors
    }

    #endregion Public Classes

    #region Private Methods

    private void ParentOnOnMessageBroadcasted(object sender, BroadcastEventArgs e)
    {
        switch (e.Message)
        {
            case "fileBrowser.itemSelected" when e.Args is FileBrowserPage.FileBrowserItemTag itemTag:
                ShowNesProperties(itemTag);
                break;
        }
    }

    private void ShowNesProperties(FileBrowserPage.FileBrowserItemTag? tag)
    {
        lv.Items.Clear();
        if (tag?.Cartridge is not null)
        {
            var mapperRegistry = Emulator.GetRegisteredMapperInfo()
                .FirstOrDefault(mi => mi.Number == tag.Cartridge.Mapper);
            var mapperName = mapperRegistry is not null ? mapperRegistry.Name : "<Unknown>";

            var lviMapper = new ListViewItem("Mapper Name")
            {
                ImageKey = @"Mapper"
            };
            lviMapper.SubItems.Add(mapperName);
            lv.Items.Add(lviMapper);

            var lviBatteryBacked = new ListViewItem("Battery Backed")
            {
                ImageKey = @"BatteryBacked"
            };
            lviBatteryBacked.SubItems.Add(tag.Cartridge?.IsBatteryBacked.ToString() ?? "<Unknown>");
            lv.Items.Add(lviBatteryBacked);

            var lviHasTrainer = new ListViewItem("Has Trainer")
            {
                ImageKey = @"User"
            };
            lviHasTrainer.SubItems.Add(tag.Cartridge?.HasTrainer.ToString() ?? "<Unknown>");
            lv.Items.Add(lviHasTrainer);

            var lviPrgRomSize = new ListViewItem("PRG ROM Size")
            {
                ImageKey = @"RomSize"
            };
            lviPrgRomSize.SubItems.Add($"{tag.Cartridge?.PrgRomSize:N0} bytes");
            lv.Items.Add(lviPrgRomSize);

            var lviPrgRomBanks = new ListViewItem("PRG ROM Banks")
            {
                ImageKey = @"Number"
            };
            lviPrgRomBanks.SubItems.Add($"{tag.Cartridge?.PrgRomBanks:N0}");
            lv.Items.Add(lviPrgRomBanks);

            var lviChrRomSize = new ListViewItem("CHR ROM Size")
            {
                ImageKey = @"RomSize"
            };
            lviChrRomSize.SubItems.Add($"{tag.Cartridge?.ChrRomSize:N0} bytes");
            lv.Items.Add(lviChrRomSize);

            var lviChrRomBanks = new ListViewItem("CHR ROM Banks")
            {
                ImageKey = @"Number"
            };
            lviChrRomBanks.SubItems.Add($"{tag.Cartridge?.ChrRomBanks:N0}");
            lv.Items.Add(lviChrRomBanks);

            var lviTvSystem = new ListViewItem("TV System")
            {
                ImageKey = @"Monitor"
            };
            lviTvSystem.SubItems.Add(Enum.GetName(typeof(TvSystem), tag.Cartridge?.TvSystem ?? TvSystem.Unknown));
            lv.Items.Add(lviTvSystem);

            var lviVramMirroring = new ListViewItem("VRAM Mirroring")
            {
                ImageKey = @"Mirroring"
            };
            lviVramMirroring.SubItems.Add(Enum.GetName(typeof(VramMirroring),
                tag.Cartridge?.Mirroring ?? VramMirroring.Unknown));
            lv.Items.Add(lviVramMirroring);
        }
    }

    #endregion Private Methods
}